#include "Adc.h"





void ADC::setVoltageReference(unsigned char flag)
{
	switch(flag)
	{
		case AREF_SEL_VREF_OFF_ADC:
			ADMUX = SetBit(ADMUX, REFS1, 0);
			ADMUX = SetBit(ADMUX, REFS0, 0);
			break;
	 	case AVCC_CAP_AT_AREF_ADC:
			ADMUX = SetBit(ADMUX, REFS1, 0);
			ADMUX = SetBit(ADMUX, REFS0, 1);
			break;
		case RESERVED_ADC:
			ADMUX = SetBit(ADMUX, REFS1, 1);
			ADMUX = SetBit(ADMUX, REFS0, 0);
			break;
		case INTERNAL_2_56_VOLT_REF_ADC:
			ADMUX = SetBit(ADMUX, REFS1, 1);
			ADMUX = SetBit(ADMUX, REFS0, 1);
			break;
		default:
			ADMUX = SetBit(ADMUX, REFS1, 0);
			ADMUX = SetBit(ADMUX, REFS0, 0);
			break;
	}
}

void ADC::setLeftAdjust(unsigned char flag)
{
	ADMUX = SetBit(ADMUX, ADLAR, flag);
}


void ADC::setEnable(unsigned char flag)
{
	ADCSRA = SetBit(ADCSRA, ADEN, flag);
}

void ADC::setStartConversion(unsigned char flag)
{
	ADCSRA = SetBit(ADCSRA, ADSC, flag);
}

void ADC::setAutoTrigger(unsigned char flag)
{
	ADCSRA = SetBit(ADCSRA, ADATE, flag);
}


void ADC::setPrescaler(unsigned char flag)
{
	switch(flag)
	{
		case Prescaler2_1_ADC:
			ADCSRA = SetBit(ADCSRA, ADPS0, 0);
			ADCSRA = SetBit(ADCSRA, ADPS1, 0);
			ADCSRA = SetBit(ADCSRA, ADPS2, 0);	
			break;
		case Prescaler2_2_ADC: 
			ADCSRA = SetBit(ADCSRA, ADPS0, 1);
			ADCSRA = SetBit(ADCSRA, ADPS1, 0);
			ADCSRA = SetBit(ADCSRA, ADPS2, 0);
			break;
		case Prescaler4_ADC:
			ADCSRA = SetBit(ADCSRA, ADPS0, 0);
			ADCSRA = SetBit(ADCSRA, ADPS1, 1);
			ADCSRA = SetBit(ADCSRA, ADPS2, 0);
			break;
		case Prescaler8_ADC:
			ADCSRA = SetBit(ADCSRA, ADPS0, 1);
			ADCSRA = SetBit(ADCSRA, ADPS1, 1);
			ADCSRA = SetBit(ADCSRA, ADPS2, 0);
			break;
		case Prescaler16_ADC:
			ADCSRA = SetBit(ADCSRA, ADPS0, 0);
			ADCSRA = SetBit(ADCSRA, ADPS1, 0);
			ADCSRA = SetBit(ADCSRA, ADPS2, 1);
			break;
		case Prescaler32_ADC:
			ADCSRA = SetBit(ADCSRA, ADPS0, 1);
			ADCSRA = SetBit(ADCSRA, ADPS1, 0);
			ADCSRA = SetBit(ADCSRA, ADPS2, 1);
			break;
		case Prescaler64_ADC:
			ADCSRA = SetBit(ADCSRA, ADPS0, 0);
			ADCSRA = SetBit(ADCSRA, ADPS1, 1);
			ADCSRA = SetBit(ADCSRA, ADPS2, 1);
			break;
		case Prescaler128_ADC:
			ADCSRA = SetBit(ADCSRA, ADPS0, 1);
			ADCSRA = SetBit(ADCSRA, ADPS1, 1);
			ADCSRA = SetBit(ADCSRA, ADPS2, 1);
			break;
		default:
			ADCSRA = SetBit(ADCSRA, ADPS0, 0);
			ADCSRA = SetBit(ADCSRA, ADPS1, 0);
			ADCSRA = SetBit(ADCSRA, ADPS2, 0);
			break;
	}
}

void ADC::setAutoTriggerSource(unsigned char flag)
{
	switch(flag)
	{
		case FreeRunningMode_ADC:
			SFIOR = SetBit(SFIOR, ADTS0, 0);
			SFIOR = SetBit(SFIOR, ADTS1, 0);
			SFIOR = SetBit(SFIOR, ADTS2, 0); 
			break;	
		case AnalogComparator_ADC:
			SFIOR = SetBit(SFIOR, ADTS0, 1);
			SFIOR = SetBit(SFIOR, ADTS1, 0);
			SFIOR = SetBit(SFIOR, ADTS2, 0); 
			break;	
		case ExternalInterruptRequest0_ADC:
			SFIOR = SetBit(SFIOR, ADTS0, 0);
			SFIOR = SetBit(SFIOR, ADTS1, 1);
			SFIOR = SetBit(SFIOR, ADTS2, 0); 
			break;	
		case Timer0_CompareMatch_ADC:
			SFIOR = SetBit(SFIOR, ADTS0, 1);
			SFIOR = SetBit(SFIOR, ADTS1, 1);
			SFIOR = SetBit(SFIOR, ADTS2, 0); 
			break;	
		case Timer0_Overflow_ADC:
			SFIOR = SetBit(SFIOR, ADTS0, 0);
			SFIOR = SetBit(SFIOR, ADTS1, 0);
			SFIOR = SetBit(SFIOR, ADTS2, 1); 
			break;	
		case Timer1_CompareMatchB_ADC:
			SFIOR = SetBit(SFIOR, ADTS0, 1);
			SFIOR = SetBit(SFIOR, ADTS1, 0);
			SFIOR = SetBit(SFIOR, ADTS2, 1); 
			break;	
		case Timer1_Overflow_ADC:
			SFIOR = SetBit(SFIOR, ADTS0, 0);
			SFIOR = SetBit(SFIOR, ADTS1, 1);
			SFIOR = SetBit(SFIOR, ADTS2, 1); 
			break;	
		case Timer1_CaptureEvent_ADC:
			SFIOR = SetBit(SFIOR, ADTS0, 1);
			SFIOR = SetBit(SFIOR, ADTS1, 1);
			SFIOR = SetBit(SFIOR, ADTS2, 1); 
			break;	
		default:
			SFIOR = SetBit(SFIOR, ADTS0, 0);
			SFIOR = SetBit(SFIOR, ADTS1, 0);
			SFIOR = SetBit(SFIOR, ADTS2, 0); 
			break;	
	}
}

void ADC::setInterrupt(unsigned char flag)
{
	ADCSRA = SetBit(ADCSRA, ADIE, flag);
}

void ADC::getData(volatile unsigned char* upperBit, 
			volatile unsigned char* lowerBit)
{
	unsigned char temp2 = ADCL; //read this one first.
	unsigned char temp1 = ADCH;

	//check the ADLAR "left adjust bit" bit in ADMUX to set the 
	// upper and lower bits.
	if(GetBit(ADMUX, ADLAR)==1)
	{//shift ADCL over 6 bits left and ADCH right 2 bits
		*(lowerBit) =(0x03&(temp2>>6)) | ((temp1<<2)&0xFB);
		*(upperBit) = (temp2>>6) & 0x03; 	
	}
	else //now set the upper and lower.
	{
		*(lowerBit) = temp2;
		*(upperBit) = temp1 & 0x03;
	}
}


void ADC::setAnalogChannelAndGain(unsigned char input, unsigned char pos, unsigned char neg, unsigned char gain)
{
	if(input == Ground_ADC)
		ADMUX = (ADMUX & 0x70) | 0x1F;
	else if(input == V_Source_ADC)
		ADMUX = (ADMUX & 0x70) | 0x1E;
	switch(gain)
	{
		case Gain10TimesADC:
			if(pos==ADC0_ADC && neg==ADC0_ADC)
				ADMUX = (ADMUX & 0x70) | 0x08;
			else if(pos==ADC1_ADC && neg==ADC0_ADC)
				ADMUX = (ADMUX & 0x70) | 0x09;
			else if(pos==ADC2_ADC && neg==ADC2_ADC)
				ADMUX = (ADMUX & 0x70) | 0x0C;
			else if(pos==ADC3_ADC && neg==ADC2_ADC)
				ADMUX = (ADMUX & 0x70) | 0x0D;
			else
				ADMUX = (ADMUX & 0x70) | 0x08;
			break;
		case Gain1TimesADC:
			if(neg==ADC1_ADC)
			{
				switch(pos)
				{
				case ADC0_ADC:
					ADMUX = (ADMUX & 0x70) | 0x10;
					break;
				case ADC1_ADC:
					ADMUX = (ADMUX & 0x70) | 0x11;
					break;
				case ADC2_ADC:
					ADMUX = (ADMUX & 0x70) | 0x12;
					break;
				case ADC3_ADC:
					ADMUX = (ADMUX & 0x70) | 0x13;
					break;
				case ADC4_ADC:
					ADMUX = (ADMUX & 0x70) | 0x14;
					break;
		 		case ADC5_ADC:
					ADMUX = (ADMUX & 0x70) | 0x15;
					break;
				case ADC6_ADC:
					ADMUX = (ADMUX & 0x70) | 0x16;
					break;
				case ADC7_ADC:
					ADMUX = (ADMUX & 0x70) | 0x17;
					break;
				case None_ADC:
					ADMUX = (ADMUX & 0x70) | 0x10;
					break;
				default:
					ADMUX = (ADMUX & 0x70) | 0x10;
					break;
				}
			}
			else if(neg==ADC2_ADC)
			{
				switch(pos)
				{
				case ADC0_ADC:
					ADMUX = (ADMUX & 0x70) | 0x18;
					break;
				case ADC1_ADC:
					ADMUX = (ADMUX & 0x70) | 0x19;
					break;
				case ADC2_ADC:
					ADMUX = (ADMUX & 0x70) | 0x1A;
					break;
				case ADC3_ADC:
					ADMUX = (ADMUX & 0x70) | 0x1B;
					break;
				case ADC4_ADC:
					ADMUX = (ADMUX & 0x70) | 0x1C;
					break;
				case ADC5_ADC:
					ADMUX = (ADMUX & 0x70) | 0x1D;
					break;
				case None_ADC:
					ADMUX = (ADMUX & 0x70) | 0x18;
					break;
				default:
					ADMUX = (ADMUX & 0x70) | 0x18;
					break;
				}
			}
			break;
		case Gain200TimesADC:
			if(pos==ADC0_ADC && neg == ADC0_ADC)
				ADMUX = (ADMUX & 0x70) | 0x0A;
			else if(pos==ADC1_ADC && neg == ADC0_ADC)
				ADMUX = (ADMUX & 0x70) | 0x0B;
			else if(pos==ADC2_ADC && neg ==ADC2_ADC)
				ADMUX = (ADMUX & 0x70) | 0x0E;
			else if(pos==ADC2_ADC && neg == ADC3_ADC)
				ADMUX = (ADMUX & 0x70) | 0x0F;
			else
				ADMUX = (ADMUX & 0x70) | 0x0A;
			break;
		case GainNoneADC:
			switch(input)
			{
				case ADC0_ADC:
					ADMUX = (ADMUX & 0x70) | 0x00;
					break;
				case ADC1_ADC:
					ADMUX = (ADMUX & 0x70) | 0x01;
					break;
				case ADC2_ADC:
					ADMUX = (ADMUX & 0x70) | 0x02;
					break;
				case ADC3_ADC:
					ADMUX = (ADMUX & 0x70) | 0x03;
					break;
				case ADC4_ADC:
					ADMUX = (ADMUX & 0x70) | 0x04;
					break;
		 		case ADC5_ADC:
					ADMUX = (ADMUX & 0x70) | 0x05;
					break;
				case ADC6_ADC:
					ADMUX = (ADMUX & 0x70) | 0x06;
					break;
				case ADC7_ADC:
					ADMUX = (ADMUX & 0x70) | 0x07;
					break;
				case None_ADC:
					ADMUX = (ADMUX & 0x70) | 0x00;
					break;
				default:
					ADMUX = (ADMUX & 0x70) | 0x00;
					break;
			}
			break;
		default:
			//b00000
			ADMUX = (ADMUX & 0x70) | 0x00;
			break;
	}
}


